<div align="center">
<img src="https://pillan.inf.uct.cl/~lrevillod/images/logo-ax-responses.png" width=250 />
</div>
<div align="center">
<h1>Axum Responses</h1>
</div>
<div align="center">
<a href="README.md" title="English README">🇺🇸 English</a>
|
<a href="README[ES].md" title="README en Español">🇪🇸 Español</a>
</div>
<div align="center">
<strong>Una forma simple de gestionar respuestas HTTP y resultados en Axum</strong>
</div>
## Descripción
**Axum Responses** es una librería diseñada para simplificar la creación y manejo de respuestas HTTP en aplicaciones construidas con [Axum](https://github.com/tokio-rs/axum). Proporciona una abstracción clara para manejar respuestas estándar y personalizadas, junto con herramientas útiles.
## Instalación
Añade la dependencia a tu `Cargo.toml`:
```toml
[dependencies]
axum_responses = "0.4.6"
```
## Características
- **Respuestas Estándar y Personalizadas**: Maneja respuestas HTTP comunes como `200 OK`, `404 Not Found`.
- **Macro Útil**: Usa la macro `response!` para simplificar la creación de respuestas con códigos de estado y cuerpos personalizados.
- **Integración con Axum**: Específicamente diseñado para trabajar con el framework Axum.
## Uso
### La Estructura `HttpResponse`
Esta estructura te permite construir respuestas con un código de estado, cuerpo JSON y encabezados personalizados usando un patrón builder.
```rust
use axum_responses::http::HttpResponse;
use serde::Serialize;
#[derive(Serialize)]
struct User {
id: u32,
username: String,
}
async fn handler() -> HttpResponse {
let user_data = User {
id: 1,
username: "example_user".to_string(),
};
HttpResponse::Created()
.message("Datos de usuario obtenidos exitosamente")
.data(user_data)
}
```
#### Respuesta Resultante
```json
{
"code": 201,
"success": true,
"message": "Datos de usuario obtenidos exitosamente",
"timestamp": "2023-10-01T12:00:00Z",
"data": {
"id": 1,
"username": "example_user"
}
}
```
Por otro lado, si respondes con un error HTTP, por ejemplo validación de datos tienes:
```rust
use axum_responses::http::HttpResponse;
use serde_json::json;
async fn error_handler() -> HttpResponse {
let validation_error = json!({
"type": "ValidationError",
"errors": [
{
"field": "username",
"message": "El nombre de usuario es requerido"
},
{
"field": "email",
"message": "El email debe ser una dirección de email válida"
}
]
});
HttpResponse::BadRequest()
.message("Datos de solicitud inválidos")
.error(validation_error)
}
```
#### Respuesta Resultante
```json
{
"code": 400,
"success": false,
"message": "Datos de solicitud inválidos",
"timestamp": "2023-10-01T12:00:00Z",
"error": {
"type": "ValidationError",
"errors": [
{
"field": "username",
"message": "El nombre de usuario es requerido"
},
{
"field": "email",
"message": "El email debe ser una dirección de email válida"
}
]
}
}
```
### La Macro `response!`
La macro `response!` te permite crear respuestas `HttpResponse` con un código de estado y un cuerpo JSON siendo más flexible. También soporta auto-serialización de estructuras que implementen `Serialize`.
```rust
use axum_responses::{response, http::HttpResponse};
async fn example_handler() -> HttpResponse {
response!(200, { "page": 10, "total": 100, "message": "Respuesta Exitosa (OK)" })
}
```
#### Respuesta Resultante
```json
{
"code": 200,
"success": true,
"message": "Respuesta Exitosa (OK)",
"timestamp": "2023-10-01T12:00:00Z",
"data": {
"page": 10,
"total": 100
}
}
```
La macro también soporta objetos únicos en el campo `data`, lo cual es útil para retornar un solo recurso o entidad. Esto está diseñado para ser similar a la notación de javascript.
```rust
use axum_responses::{response, http::HttpResponse};
use serde::Serialize;
#[derive(Serialize)]
struct Product {
id: String,
name: String,
price: f64,
}
async fn product_handler() -> HttpResponse {
let product_data = Product {
id: "prod_123".to_string(),
name: "Producto de Ejemplo".to_string(),
price: 99.99,
};
response!(201, { product_data })
}
```
#### Respuesta Resultante
```json
{
"code": 201,
"success": true,
"message": "Created",
"timestamp": "2023-10-01T12:00:00Z",
"data": {
"id": "prod_123",
"name": "Producto de Ejemplo",
"price": 99.99
}
}
```
## Cambios Importantes
- Si los metodos `data`, `error`, o `errors` no son llamados, esos campos no serán añadidos en la respuesta final. Anteriormente el campo data era añadido como `nulo` incluso si no tenía asignado valores.
- Se removió el enum `Response` de forma definitiva.
- El enum `Response` ha sido deprecado a favor de la estructura `HttpResponse`.
- El tipo `ControllerResult` ha sido eliminado, y ahora puedes usar `Result<T, HttpResponse>` directamente en tus manejadores, crear tu propio tipo Result personalizado, o simplemente usar `HttpResponse` directamente.
- La librería ahora implementa convenciones RFC para respuestas HTTP.